//
// Created by 98770 on 2023/6/22.
//

#ifndef NETWORK_SERVERCONTROL_H
#define NETWORK_SERVERCONTROL_H
#define DEFAULT_DNS_SERVER "223.5.5.5"
#define MAX_BUFFER_SIZE
#include "libCache.h"
#include "ISPquery.h"
#include <time.h>


#if _WIN32

#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")

#else

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#endif


typedef struct dns_header dns_header;
//按字节对齐，否则对dns报文的解析会因编译器对齐出错
#pragma pack(1)
struct dns_header {
    uint16_t     query_id;
    uint16_t     flags;
    uint16_t     qdcount;
    uint16_t     ancount;
    uint16_t     nscount;
    uint16_t     arcount;
};
struct DNS_answer{
    unsigned short class;
    unsigned short type;
    char domain[256];
    char ip[256];
    int ttl;
    char packet[1024];
    int len;
};
struct  DNSResourceRecord{
    uint16_t name;
    uint16_t type;
    uint16_t class;
    uint32_t ttl;
    uint16_t rdlength;
    uint32_t rdata;
};
#pragma pack()

bool initStaticCache(struct hashmap_s*hashmap,char* filename);
bool initDynamicCache(struct hashmap_s*hashmap);
bool initServer(struct hashmap_s*staticHashmap,char* filename,struct hashmap_s*dynamicHashmap);
char* resolveQuery(struct hashmap_s*staticHashmap,struct hashmap_s* dynamicHashmap,char*packet,int len,char *DNSserver);
char* resolveByStaticCache(struct hashmap_s*hashmap,char*domainName);
char* resolveByDynamicCache(struct hashmap_s*hashmap,char*domainName);
uint32_t resolveTTLonCache(struct hashmap_s*hashmap,char*domainName);
cacheNode* resolveByInternet(char *packet,int len,char *DNSserver);
int buildResponse(char *request, char *response, char *ip, int len,uint32_t ttl);
char* getDomainName(char*packet,int len);
bool processQuery(int s,struct sockaddr_in* si_in,struct hashmap_s*staticHashmap,struct hashmap_s* dynamicHashmap,char*packet,int len,char *DNSserver);
void* refreshCacheForUnix(void *cache);
void refreshCacheForWin32(void *cache);
void storeTypeARecord(struct hashmap_s*hashmap, char *response, int len);
void IDAssignForQuery(char *packet);
void IDAssignForResponse(char *packet);
char* getFullName(char* dnsHeader, uint16_t offset);
int DNSListIn(char *filename);
char* DNSGet();
void DNSFree();
//生成随机数
uint16_t generateRandom16bit();
#endif //NETWORK_SERVERCONTROL_H
